//: concurrency/MapComparisons.java
// {Args: 1 10 10} (Fast verification check during build)
// Rough comparison of thread-safe Map performance.
package concurrency;

import java.util.concurrent.*;
import java.util.*;

import net.mindview.util.*;

abstract class MapTest extends Tester<Map<Integer, Integer>>
{
    MapTest(String testId, int nReaders, int nWriters)
    {
        super(testId, nReaders, nWriters);
    }
    
    class Reader extends TestTask
    {
        long result = 0;
        
        void test()
        {
            for (long i = 0; i < testCycles; i++)
                for (int index = 0; index < containerSize; index++)
                    result += testContainer.get(index);
        }
        
        void putResults()
        {
            readResult += result;
            readTime += duration;
        }
    }
    
    class Writer extends TestTask
    {
        void test()
        {
            for (long i = 0; i < testCycles; i++)
                for (int index = 0; index < containerSize; index++)
                    testContainer.put(index, writeData[index]);
        }
        
        void putResults()
        {
            writeTime += duration;
        }
    }
    
    void startReadersAndWriters()
    {
        for (int i = 0; i < nReaders; i++)
            exec.execute(new Reader());
        for (int i = 0; i < nWriters; i++)
            exec.execute(new Writer());
    }
}

class SynchronizedHashMapTest extends MapTest
{
    Map<Integer, Integer> containerInitializer()
    {
        return Collections.synchronizedMap(new HashMap<Integer, Integer>(
            MapData.map(new CountingGenerator.Integer(), new CountingGenerator.Integer(), containerSize)));
    }
    
    SynchronizedHashMapTest(int nReaders, int nWriters)
    {
        super("Synched HashMap", nReaders, nWriters);
    }
}

class ConcurrentHashMapTest extends MapTest
{
    Map<Integer, Integer> containerInitializer()
    {
        return new ConcurrentHashMap<Integer, Integer>(
            MapData.map(new CountingGenerator.Integer(), new CountingGenerator.Integer(), containerSize));
    }
    
    ConcurrentHashMapTest(int nReaders, int nWriters)
    {
        super("ConcurrentHashMap", nReaders, nWriters);
    }
}

public class MapComparisons
{
    public static void main(String[] args)
    {
        Tester.initMain(args);
        new SynchronizedHashMapTest(10, 0);
        new SynchronizedHashMapTest(9, 1);
        new SynchronizedHashMapTest(5, 5);
        new ConcurrentHashMapTest(10, 0);
        new ConcurrentHashMapTest(9, 1);
        new ConcurrentHashMapTest(5, 5);
        Tester.exec.shutdown();
    }
} /*
   * Output: (Sample) Type Read time Write time Synched HashMap 10r 0w 306052025049 0 Synched HashMap 9r 1w 428319156207
   * 47697347568 readTime + writeTime = 476016503775 Synched HashMap 5r 5w 243956877760 244012003202 readTime +
   * writeTime = 487968880962 ConcurrentHashMap 10r 0w 23352654318 0 ConcurrentHashMap 9r 1w 18833089400 1541853224
   * readTime + writeTime = 20374942624 ConcurrentHashMap 5r 5w 12037625732 11850489099 readTime + writeTime =
   * 23888114831
   */// :~
